package org.kl.auditsupervision.service.fnd;

import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.kl.bf.service.BasicService;
import org.kl.bf.service.ServiceException;
import org.kl.auditsupervision.entity.fnd.Org;
import org.kl.auditsupervision.repository.fnd.OrgDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import org.springside.modules.utils.Collections3;

import com.alibaba.fastjson.JSON;

/**
 * @author Code Generator
 * @since 2015-09-09 10:59:57
 * @see 组织机构表 组织机构表
 */
// Spring Bean的标识.
@Component
// 默认将类中的所有public函数纳入事务管理.
@Transactional
public class OrgService extends BasicService<Org> {
	@Autowired
	private OrgDao orgDao;

	public void save(Org entity,
			@RequestParam(value = "inserted") String detailInserted,
			@RequestParam(value = "updated") String detailUpdated,
			@RequestParam(value = "deleted") String detailDeleted) {
		orgDao.save(entity);
		if (StringUtils.isNotBlank(detailInserted)) {
			List<Org> inserts = JSON.parseArray(detailInserted, Org.class);
			if (Collections3.isNotEmpty(inserts)) {
				for (Org a : inserts) {
					// 增加与主表相关的数据复制代码
					orgDao.save(a);
				}
			}
		}
		if (StringUtils.isNotBlank(detailUpdated)) {
			List<Org> updates = JSON.parseArray(detailUpdated, Org.class);
			if (Collections3.isNotEmpty(updates)) {
				for (Org b : updates) {
					orgDao.save(b);
				}
			}
		}
		if (StringUtils.isNotBlank(detailDeleted)) {
			List<Org> deletes = JSON.parseArray(detailDeleted, Org.class);
			if (Collections3.isNotEmpty(deletes)) {
				orgDao.delete(deletes);
			}
		}
	}

	public List<Org> getAllOrg() {
		return orgDao.findAll(new Sort(Direction.ASC, "orgNo"));
	}

	public List<Org> findById(String id) {
		return orgDao.findById(id);
	}

	public List<Org> findByParentOrgId(String id) {
		return orgDao.findByParentOrgId(id);
	}

	public List<Org> findByOrgNo(String orgNo) {
		return orgDao.findByOrgNo(orgNo);
	}

	public List<Org> findByRootOrgIdAndOrgLevel(String rootOrgId,
			String orgLevel) {
		return orgDao.findByRootOrgIdAndOrgLevel(rootOrgId, orgLevel);
	}

	public int childrenCount(final String pcode) {
		Specification<Org> spec = new Specification<Org>() {
			public Predicate toPredicate(Root<Org> root,
					CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate p2 = cb.equal(root.get("parentOrgId")
						.as(String.class), pcode);
				query.where(p2);
				return query.getRestriction();
			}
		};
		return (int) orgDao.count(spec);
	}

	public int batchDeleteOrg(String ids) {
		String[] idArray = ids.split(",");
		int deletedCount = 0;
		for (String id : idArray) {
			if (StringUtils.isBlank(id)) {
				continue;
			}
			Org org = orgDao.findOne(id);
			int count = childrenCount(org.getOrgNo());
			if (count != 0) {
				throw new ServiceException(org.getOrgNo() + "--"
						+ org.getOrgName() + "不是叶子节点，不能删除");
			}
			deletedCount++;
		}
		for (String id : idArray) {
			if (StringUtils.isBlank(id)) {
				continue;
			}
			orgDao.delete(id);
		}
		return deletedCount;
	}

	public String getAllParentOrgIdWithQuotes(String id, String allParentOrgId) {
		return getAllParentOrgId(id, allParentOrgId, "'");
	}

	public String getAllParentOrgId(String id, String allParentOrgId) {
		return getAllParentOrgId(id, allParentOrgId, "");
	}

	private String getAllParentOrgId(String id, String allParentOrgId,
			String connectString) {
		Org org = orgDao.getOne(id);
		if (StringUtils.isNotBlank(org.getParentOrgId())) {
			Org parentOrg = orgDao.getOne(org.getParentOrgId());
			if (StringUtils.isBlank(allParentOrgId)) {
				allParentOrgId = connectString + parentOrg.getParentOrgId()
						+ connectString;
			} else {
				allParentOrgId = connectString+parentOrg.getParentOrgId()+connectString + ","
						+ allParentOrgId;
			}

			if (StringUtils.isNotBlank(parentOrg.getParentOrgId())) {
				allParentOrgId = getAllParentOrgId(parentOrg.getId(),
						allParentOrgId);
			}
		}
		return allParentOrgId;
	}

	public String getAllChildOrgIdWithQuotes(String id, String allChildOrgId) {
		return getAllChildOrgId(id, allChildOrgId, "'");

	}

	public String getAllChildOrgId(String id, String allChildOrgId) {
		return getAllChildOrgId(id, allChildOrgId, "");

	}

	private String getAllChildOrgId(String id, String allChildOrgId,
			String connectString) {
		List<Org> orgList = orgDao.findByParentOrgId(id);
		for (Org org : orgList) {
			if (StringUtils.isBlank(allChildOrgId)) {
				allChildOrgId = connectString + org.getId() + connectString;
			} else {
				allChildOrgId = connectString+org.getId() + connectString+ "," + allChildOrgId;
			}
			List<Org> orgChildList = orgDao.findByParentOrgId(org.getId());
			if (Collections3.isNotEmpty(orgChildList)) {
				for (Org orgChild : orgChildList) {
					allChildOrgId = getAllChildOrgId(orgChild.getId(),
							allChildOrgId);
				}
			}
		}

		return allChildOrgId;
	}
}
